package com.uk.ui.fatura;



import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.uk.HandleMessages;
import com.uk.data.containers.TarifaContainer;
import com.uk.data.containers.TarifaFaturaContainer;
import com.uk.data.ejbs.IFaturaBean;
import com.uk.data.entities.Fatura;
import com.uk.data.entities.Kontrata;
import com.uk.data.entities.Tarifa;
import com.uk.exceptions.NestedException;
import com.uk.interfaces.PopupWindowListener;
import com.uk.reports.ReportWindow;
import com.uk.reports.Reports;
import com.uk.ui.windows.FaturaSelectWindow;
import com.uk.ui.windows.KontrataSelectWindow;
import com.uk.ui.windows.TarifaSelectWindow;
import com.vaadin.data.Validator;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.validator.DoubleValidator;
import com.vaadin.event.FieldEvents;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.PopupDateField;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class FaturaForm extends VerticalLayout implements PopupWindowListener, Button.ClickListener, FieldEvents.TextChangeListener {

	private  final Button findKontrata = new Button("Zgjidh klientin");
	private TarifaContainer tarifaContainer;
	private Table tarifaListTable = new Table();
	private final Button addTarifa = new Button("+");
	private final Button removeTarifa = new Button("-");
	private KontrataInfo kontraInfo = new KontrataInfo();
	private HorizontalLayout footerLayout = new HorizontalLayout();
	
	private Kontrata kontrata;

	private KontrataSelectWindow kontrataSelectWindow;
	private TarifaSelectWindow tarifaSelectWindow;
	private FaturaSelectWindow faturaSelectWindow;
	
	private IFaturaBean faturaBean;
	private final Button saveFatura = new Button("RUAJ");
	private Label errorMessage = new Label("",Label.CONTENT_XHTML);
	
	private final TextField harxhimiAfrofe = new TextField();
	private final PopupDateField dataKaluar = new PopupDateField();
	private final TextField leximiKaluar = new TextField();
	private final PopupDateField dataAktual = new PopupDateField();
	private final TextField leximiAktual = new TextField();
	private final Label harxhimi = new Label("<font size='4' color='blue'>-</font>", Label.CONTENT_XHTML);
	private final Label harxhimiTotal = new Label("<font size='4' color='blue'>-</font>",Label.CONTENT_XHTML);
	private final Button findFaturaKaluar = new Button("+");
	
	
	public void resetForm(){
		this.kontraInfo.clearKontrata();
		this.dataAktual.setValue(null);
		this.leximiAktual.setValue(0d);
		this.dataKaluar.setValue(null);
		this.leximiKaluar.setValue(0d);
		this.harxhimiAfrofe.setValue(0d);
		
		harxhimi.setValue("<font size='4' color='blue'>-</font>");
		this.harxhimiTotal.setValue("<font size='4' color='blue'>-</font>");
		this.setSasiaOnTarifaListTable(0);
	}
	
	public FaturaForm(FaturaPanel faturaPanel){
		setMargin(true);
		setSpacing(true);

		findFaturaKaluar.setDescription("Shfaq leximin e muajit te kaluar");
		findFaturaKaluar.addListener(this);
		this.faturaBean = faturaPanel.getFaturaBean();
		this.kontrataSelectWindow = new KontrataSelectWindow(this, this.faturaBean);
		this.tarifaSelectWindow = new TarifaSelectWindow(this, this.faturaBean);
		this.faturaSelectWindow = new FaturaSelectWindow(this, faturaBean);
		
		//Kontrata
		this.kontraInfo = new KontrataInfo();
		this.findKontrata.addListener(this);
		this.kontraInfo.addComponent(this.findKontrata);
		this.addComponent(this.kontraInfo);
		
		
		//Leximi & Harxhimi
		//afrofe = faturaBean.getAfrofe();
		this.addComponent(this.loadLeximiInfo());
		
		// Tarifa
		
		this.addComponent(this.loadTarifaInfo());
		
		this.saveFatura.addListener(this);
		footerLayout.setSpacing(true);
		footerLayout.addComponent(saveFatura);
		footerLayout.addComponent(errorMessage);
		
		
		
		this.addComponent(footerLayout);


	}

	
	
	
	
	private HorizontalLayout loadLeximiInfo(){
		leximiAktual.addStyleName("align-right");
		leximiAktual.setValue("0.0");
		leximiAktual.addListener(this);
		leximiAktual.addValidator(new DoubleValidator("Leximi duhet te jete numer"));
		leximiAktual.setImmediate(true);
		
		
		leximiKaluar.addStyleName("align-right");
		leximiKaluar.setValue("0.0");
		leximiKaluar.addListener(this);
		leximiKaluar.addValidator(new DoubleValidator("Leximi duhet te jete numer"));
		leximiKaluar.setImmediate(true);
		
		harxhimiAfrofe.addStyleName("align-right");
		harxhimiAfrofe.addListener(this);
		harxhimiAfrofe.setValue("0.0");
		harxhimiAfrofe.addValidator(new DoubleValidator("Harxhimi duhet te jete numer"));
		harxhimiAfrofe.setImmediate(true);
		
		
		this.dataAktual.setDateFormat("dd/MM/yyyy");
		this.dataAktual.setRequired(true);
		this.dataAktual.setRequiredError("Data aktuale nuk mund te jete bosh");
		this.dataAktual.addValidator(new Validator() {
			
			@Override
			public void validate(Object value) throws InvalidValueException {
				
				if (!isValid(value)) throw new InvalidValueException("Data aktuale e leximit duhet te jete me e madhe se data e kaluar.");
			}
			
			@Override
			public boolean isValid(Object value) {
				if (dataKaluar.getValue() == null) return true;
				if (value !=null ){
					Date data = (Date) value;
					if (data.before((Date) dataKaluar.getValue())) return false;
					
				}
				return true;
			}
		});
		this.dataKaluar.setDateFormat("dd/MM/yyyy");
		
		final GridLayout gridLayout = new GridLayout(3,6);
		gridLayout.setWidth(600, Sizeable.UNITS_PIXELS);
		gridLayout.setHeight(150, Sizeable.UNITS_PIXELS);
		
		final Label periudhaLabel = new Label("<strong>PERIUDHA</strong>",Label.CONTENT_XHTML);
	
		gridLayout.addComponent(periudhaLabel);

		final Label dataLabel = new Label("<strong>DATA</strong>",Label.CONTENT_XHTML);
		gridLayout.addComponent(dataLabel);

		final Label leximiLabel = new Label("<strong>LEXIMI</strong>",Label.CONTENT_XHTML);
		gridLayout.addComponent(leximiLabel);
		
		gridLayout.addComponent(new Label("Muaji aktual"));
		gridLayout.addComponent(dataAktual);
		gridLayout.addComponent(leximiAktual);

		gridLayout.addComponent(new Label("Muaji kaluar"));
		gridLayout.addComponent(dataKaluar);
		
		HorizontalLayout lex = new HorizontalLayout();
		lex.addComponent(leximiKaluar);
		lex.addComponent(findFaturaKaluar);
		
		gridLayout.addComponent(lex);
		final Label harxhimiLabel = new Label("<strong>Harxhimi</strong>", Label.CONTENT_XHTML);
		gridLayout.addComponent(harxhimiLabel,0, 3, 1, 3);

		gridLayout.addComponent(harxhimi, 2, 3);
		final Label harxhimiAfrofeLabel = new Label("<strong>Harxhimi Afrore</strong>", Label.CONTENT_XHTML);
		gridLayout.addComponent(harxhimiAfrofeLabel,0, 4, 1, 4);

		gridLayout.addComponent(harxhimiAfrofe, 2, 4);
		
		
		gridLayout.addComponent(new Label("<strong>Harxhimi total</strong>", Label.CONTENT_XHTML), 0, 5, 1, 5);
		gridLayout.addComponent(harxhimiTotal, 2, 5);
	
		
		gridLayout.setStyleName("gridexample");
		gridLayout.setSpacing(true);
		
		HorizontalLayout hl = new HorizontalLayout();
		hl.setSpacing(true);
		hl.addComponent(gridLayout);
		
		
		return hl;
		
	}
	
	TarifaFaturaContainer tarifaFaturaContainer = new TarifaFaturaContainer(TarifaFatura.class);
	

	private GridLayout loadTarifaInfo(){
		
		GridLayout grid = new GridLayout(3,1);
		this.tarifaContainer = TarifaContainer.createFromEjb(this.faturaBean, true);
			
		Collection<Tarifa> col = this.tarifaContainer.getItemIds();
		
		double totali = 0;
		
		List<TarifaFatura> tarifaFaturas = new ArrayList<TarifaFatura>();
		
		
		
		for (Iterator iterator = col.iterator(); iterator.hasNext();) {
			Tarifa tarifa = (Tarifa) iterator.next();
			
			TarifaFatura tarifaFatura = new TarifaFatura();
			tarifaFatura.setId(tarifa.getId());
			tarifaFatura.setKodi(tarifa.getKodi());
			tarifaFatura.setPershkrimi(tarifa.getPershkrimi());
			tarifaFatura.setNjesia(tarifa.getNjesia());
			
			tarifaFatura.setCmimi(tarifa.getCmimi());
			tarifaFatura.setAplikoTvsh(tarifa.isAplikoTVSH());
			
			
			
			double sasia = 0;
			
			if (tarifa.getNjesia() != null && tarifa.getNjesia().toLowerCase().equals("m3")){
				sasia = 0;
			}
			else{
				sasia = 1;
			}
	
			tarifaFatura.setSasia(sasia);

			double vlera =  sasia * tarifa.getCmimi();
			

			totali += vlera;
			tarifaFatura.setVlera(vlera + tarifaFatura.getTvsh());
			
			tarifaFaturas.add(tarifaFatura);
		}
		
		tarifaFaturaContainer.addAll(tarifaFaturas);
		
		tarifaListTable.setContainerDataSource(tarifaFaturaContainer);
		tarifaListTable.setPageLength(4);
	
		tarifaListTable.setSelectable(true);
		tarifaListTable.setImmediate(true);
		tarifaListTable.setSortDisabled(true);
		tarifaListTable.setWidth("600px");
		tarifaListTable.setFooterVisible(true);
		tarifaListTable.setColumnFooter("kodi", "Totali");

		tarifaListTable.setVisibleColumns(new String[]{  "kodi","pershkrimi", "njesia", "sasia", "cmimi", "tvsh", "vlera"});
		tarifaListTable.setColumnHeaders(new String[]{ "Kodi","Pershkrimi", "Njesia", "Sasia", "Cmimi", "TVSH(20%)", "Vlera"});
		tarifaListTable.setColumnAlignment("sasia",Table.ALIGN_RIGHT );
		tarifaListTable.setColumnAlignment("cmimi",Table.ALIGN_RIGHT );
		tarifaListTable.setColumnAlignment("tvsh",Table.ALIGN_RIGHT );
		tarifaListTable.setColumnAlignment("vlera",Table.ALIGN_RIGHT );
		
		
		grid.addComponent(tarifaListTable);
		
		this.addTarifa.addListener(this);
		this.removeTarifa.addListener(this);
		
		grid.addComponent(addTarifa);
		grid.addComponent(removeTarifa);
		grid.setComponentAlignment(addTarifa, Alignment.TOP_LEFT);
		return grid;
	}
	
	private double totali;
	
	private void setSasiaOnTarifaListTable(double s){
	
		List<TarifaFatura> col = (List<TarifaFatura>) this.tarifaFaturaContainer.getItemIds();
		
		totali = 0;
		
		int i = 0;
		for (TarifaFatura tarifaFatura : col) {
			double sasia = 0;
			if (tarifaFatura.getNjesia() != null && tarifaFatura.getNjesia().toLowerCase().equals("m3")){
				sasia = s;
			}
			else{
				sasia = 1d;
			}
			tarifaFatura.setSasia(sasia);
			double vlera =  sasia * tarifaFatura.getCmimi();
			boolean tvsh = tarifaFatura.isAplikoTvsh();
			if (tvsh ){
				vlera = vlera + vlera*20/100; 
			}
			tarifaFatura.setVlera(vlera);
			totali += vlera;
			tarifaListTable.setColumnFooter("vlera", (new Double(totali)).toString() );
			
			col.set(i, tarifaFatura);
			
			i+=1;
			System.out.println("FaturaForm.setSasiaOnTarifaListTable()");
		}
		
		tarifaFaturaContainer.removeAllItems();
		tarifaFaturaContainer.addAll(col);
	
	}
	
	private void addRowToTarifaList(Tarifa tarifa, double sasia){
		
		TarifaFatura tarifaFatura = new TarifaFatura();
		tarifaFatura.setId(tarifa.getId());
		tarifaFatura.setKodi(tarifa.getKodi());
		tarifaFatura.setPershkrimi(tarifa.getPershkrimi());
		tarifaFatura.setNjesia(tarifa.getNjesia());
		
		tarifaFatura.setCmimi(tarifa.getCmimi());
		tarifaFatura.setAplikoTvsh(tarifa.isAplikoTVSH());
		if (tarifa.getNjesia().toLowerCase().trim().equals("m3")){
			tarifaFatura.setSasia(sasia);
		}
		else
			tarifaFatura.setSasia(1d);
		
		Double vlera = sasia * tarifa.getCmimi();
		if (tarifa.isAplikoTVSH()){
			vlera = vlera + 20/100*vlera;
		}
		tarifaFatura.setVlera(vlera);
		
		this.tarifaFaturaContainer.addItem(tarifaFatura);
	
	}
	
	@Override
	public void returnAction(Object object) {
		if (object == this.kontrataSelectWindow){
			this.kontrata = this.kontrataSelectWindow.getSelectedKontrata();
			this.kontraInfo.loadKontrata(this.kontrata);
		}
		else if (object == this.tarifaSelectWindow){
			Tarifa selectedTarifa = this.tarifaSelectWindow.getSelectedTarifa();
	
			List<TarifaFatura> col = (List<TarifaFatura>) this.tarifaFaturaContainer.getItemIds();
			for (TarifaFatura tarifaFatura : col) {
				if (tarifaFatura.getKodi().equals(selectedTarifa.getKodi())){
					Window.Notification n = new Window.Notification("Info",
			                Window.Notification.TYPE_TRAY_NOTIFICATION);
			        n.setPosition(Window.Notification.POSITION_CENTERED);
			        n.setDescription("Tarifa e zgjedhur ndodhet ne liste !");
			        getWindow().showNotification(n);
					return;
				}
			}
			

			try {
				double sasia = new Double(harxhimi.getValue().toString());
				this.addRowToTarifaList(selectedTarifa, sasia);
			} catch (Exception e) {
				this.addRowToTarifaList(selectedTarifa, 0);
			}
			
			
		}
		
		else if (object == faturaSelectWindow){
			this.dataKaluar.setValue(faturaSelectWindow.getSelectedFatura().getDataLeximAktual());
			this.leximiKaluar.setValue(faturaSelectWindow.getSelectedFatura().getLeximiAktual());
			leximiChanged();
			
			
		}
		
	}
	

	
	@Override
	public void buttonClick(ClickEvent event) {
		
		
		try {
			
			if (event.getComponent() == this.findKontrata){
				getApplication().getMainWindow().addWindow(kontrataSelectWindow);
			}
			else if (event.getComponent() == this.addTarifa){
				getApplication().getMainWindow().addWindow(tarifaSelectWindow);
			}
			else if (event.getComponent() == this.removeTarifa){
				if (this.tarifaListTable.getValue() != null){
					TarifaFatura tf = (TarifaFatura) this.tarifaListTable.getValue();
					//this.tarifaContainer.removeItem(this.faturaBean.queryTarifaById(new Integer(this.icTarifa.getContainerProperty(this.tarifaListTable.getValue(), "Id").getValue().toString())));
					this.tarifaFaturaContainer.removeItem(this.faturaBean.queryTarifaById(tf.getId()));
					this.tarifaListTable.removeItem(this.tarifaListTable.getValue());
				}
			
			}
			else if (event.getComponent() == this.findFaturaKaluar){
				
				if (kontrata == null){
					Window.Notification n = new Window.Notification("Info",
			                Window.Notification.TYPE_TRAY_NOTIFICATION);
			        n.setPosition(Window.Notification.POSITION_CENTERED);
			        n.setDescription("Duhet te zgjidhni kontraten !");
			        getWindow().showNotification(n);
					return;
				}
				faturaSelectWindow.setKontrata(this.kontrata);
				getApplication().getMainWindow().addWindow(faturaSelectWindow);
				
			}
			else if (event.getComponent() == this.saveFatura){
				
				if (validate()){
					Fatura fatura = new Fatura();
					fatura.setKontrata(this.kontrata);
					
					fatura.setTarifaCollection((List<Tarifa>) this.tarifaContainer.getItemIds());
					fatura.setDataLeximAktual((Date) dataAktual.getValue());
					fatura.setDataLeximKaluar((Date) dataKaluar.getValue());
					fatura.setLeximiAktual(new Double(leximiAktual.getValue().toString()));
					fatura.setLeximiKaluar(new Double(leximiKaluar.getValue().toString()));
					
					fatura.setTotali(totali);
					
					fatura.setHarxhimiAfrofe(Double.parseDouble(this.harxhimiAfrofe.getValue().toString()));
					fatura = this.faturaBean.saveFatura(fatura);
					if (fatura != null){
						System.out.println("FaturaForm.buttonClick()");
						this.loadConfirmationWindow(fatura);
					}
					
				}
			}
		} catch (Exception e) {
			HandleMessages.showErrorOnScreen(e, this);
		}
			
	}
	
	private void loadConfirmationWindow(Fatura f){
		final Window confWin = new Window("Konfirmim");
		confWin.center();
		final Fatura fat = f;
		Label label = new Label("Fatura u ruajt me sukses !");
		confWin.addComponent(label);
		Button print = new Button("Printo fature", new Button.ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {
				try {
					getWindow().removeWindow(confWin);
					getApplication().getMainWindow().addWindow(new ReportWindow(getApplication(), Reports.buildFaturaReport(fat))) ;
					
				} catch (Exception e) {
					HandleMessages.showErrorOnScreen(e, event.getComponent());
				}
				
				
			}
		});
		confWin.addComponent(print);
		this.getWindow().addWindow(confWin);
		
	}
	
	
	
	private boolean validate() {

		if (kontrata == null) {
			this.showErrorMessage("<font color='red'>Duhet te zgjidhni kontraten!</font>");
			return false;
		}

		if (harxhimi == null || "".equals(harxhimi.toString().trim())){
			this.showErrorMessage("<font color='red'>Duhet te specifikohet harxhimi!</font>");
			return false;
		}
		else{
			Double dob;
			try {
				dob = Double.parseDouble(leximiAktual.getValue().toString());
				dob = Double.parseDouble(leximiKaluar.getValue().toString());
				dob = Double.parseDouble(harxhimiAfrofe.getValue().toString());
			} catch (Exception e) {
				this.showErrorMessage("Harxhimi duhet te jete numer!");
				return false;
			}
			
			if (dob < 0){
				this.showErrorMessage("Harxhimi duhet te jete numer pozitiv!");
				return false;
				
			}
			
		}
		
		if (!this.dataAktual.isValid()){
			this.showErrorMessage("Data e leximit aktual duhet te jete me e madhe se data e leximit te kaluar!");
			return false;
		}
		this.removeErrorMessage();
		
		return true;
	}

	
	private void showErrorMessage(String value){
		this.errorMessage.setValue("<font color='red'  size='4'><b>" + value + "</b></font>");
	
	}
	
	private void removeErrorMessage(){
		this.errorMessage.setValue("");
	}
	
	

	public IFaturaBean getFaturaBean() {
		return faturaBean;
	}

	@Override
	public void textChange(TextChangeEvent event) {
		try {
			Double h1 = 0d; Double h2 = 0d;
			Double afrofe = 0d;
			
			if (event.getComponent() == leximiAktual){
				h1 = new Double(event.getText());
				h2 = new Double(leximiKaluar.getValue().toString());
				afrofe = new Double(harxhimiAfrofe.getValue().toString());
				
				
			}
			else if (event.getComponent() == leximiKaluar){
				h1 = new Double(leximiAktual.getValue().toString());
				h2 = new Double(event.getText());
				afrofe = new Double(harxhimiAfrofe.getValue().toString());
	
			}
			else if (event.getComponent() == harxhimiAfrofe){
				h1 = new Double(leximiAktual.getValue().toString());
				h2 = new Double(leximiKaluar.getValue().toString());
				afrofe = new Double(event.getText());
			}

			harxhimi.setValue("<font size='4' color='blue'>" + Double.toString((h1-h2)) + "</font>");
			harxhimiTotal.setValue("<font size='4' color='blue'>" + Double.toString((h1-h2) + afrofe) + "</font>");
			setSasiaOnTarifaListTable((h1-h2) + afrofe);
			
			
		} catch (Exception e) {
			harxhimi.setValue( "<font size='4' color='red'>Vlera te pasakta</font>");
			harxhimiTotal.setValue("<font size='4' color='red'>Vlera te pasakta</font>");
			setSasiaOnTarifaListTable(0);
		}
		
	}


	private void leximiChanged(){
		try {
			Double h1 = 0d; Double h2 = 0d;
			Double afrofe = 0d;
			
			
				h1 = new Double(leximiAktual.getValue().toString());
				h2 = new Double(leximiKaluar.getValue().toString());
				afrofe = new Double(harxhimiAfrofe.getValue().toString());

			harxhimi.setValue("<font size='4' color='blue'>" + Double.toString((h1-h2)) + "</font>");
			harxhimiTotal.setValue("<font size='4' color='blue'>" + Double.toString((h1-h2) + afrofe) + "</font>");
			setSasiaOnTarifaListTable((h1-h2) + afrofe);
			
			
		} catch (Exception e) {
			harxhimi.setValue( "<font size='4' color='red'>Vlera te pasakta</font>");
			harxhimiTotal.setValue("<font size='4' color='red'>Vlera te pasakta</font>");
			setSasiaOnTarifaListTable(0);
		}
	}
	

	
}
